﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="TopicActioner.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The topic actioner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Actioners.Activities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using NHibernate;

    using ServiceLibrary.Models.Base;
    using ServiceLibrary.Models.Domain;
    using ServiceLibrary.Services.Commands;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;

    /// <summary>
    /// The topic actioner.
    /// </summary>
    public class TopicActioner : ActionerBase
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TopicActioner"/> class.
        /// </summary>
        /// <param name="session">
        /// The session.
        /// </param>
        /// <param name="activeUser">
        /// The active user.
        /// </param>
        public TopicActioner(ISession session, User activeUser)
            : base(session, activeUser)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create topic.
        /// </summary>
        /// <param name="title">
        /// The title.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        public Guid CreateTopic(string title)
        {
            var topic = new Topic
                            {
                                Title = title, 
                                CreatedDateTime = DateTime.Now, 
                                ID = Guid.NewGuid()
                            };
            this.Session.Save(topic);

            this.Log.CreateLogEntry(
                topic.ID, 
                string.Format("Emne '{0}', blev oprettet.", topic.Title),
                Enums.LogEntryType.Topic,
                Enums.LogEntryActionType.Create);

            return topic.ID;
        }

        /// <summary>
        /// The execute search query.
        /// </summary>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <returns>
        /// The <see cref="TopicResult"/>.
        /// </returns>
        public TopicResult ExecuteSearchQuery(TopicQuery query)
        {
            SearchSettings settings = query.Settings;

            var result = new TopicResult();

            IQueryOver<Topic, Topic> search = this.Session.QueryOver<Topic>();
            this.ApplyDefaultCriterias(settings, search);

            int rowCount = search.RowCount();
            var topics = this.ApplySkipAndTake(settings, this.Sort(search.List()));

            result.TotalRowCount = rowCount;

            foreach (Topic topic in topics)
            {
                Services.Dto.Topic dto = Services.Dto.Topic.Convert(topic);
                if (dto != null)
                {
                    result.List.Add(dto);
                }
            }

            return result;
        }

        /// <summary>
        /// The get user.
        /// </summary>
        /// <param name="id">
        /// The id.
        /// </param>
        /// <returns>
        /// The <see cref="Topic"/>.
        /// </returns>
        public Topic GetUser(Guid id)
        {
            var topic = this.Session.Get<Topic>(id);

            return topic;
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create topic.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void CreateTopic(CreateTopicCommand cmd)
        {
            if (cmd.Dto != null)
            {
                var topic = new Topic();
                topic.Title = cmd.Dto.Title;
                topic.ID = cmd.Dto.ID;
                this.Session.Save(topic);

                this.Log.CreateLogEntry(
                    topic.ID, 
                    string.Format("Emne '{0}', blev oprettet.", topic.Title), 
                    Enums.LogEntryType.Topic, 
                    Enums.LogEntryActionType.Create);
            }
        }

        /// <summary>
        /// The delete topic.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void DeleteTopic(DeleteTopicCommand cmd)
        {
            var topic = this.Session.Get<Topic>(cmd.Dto);

            if (topic == null)
            {
                return;
            }

            var topicUsage =
                this.Session.QueryOver<BusinessDevelopmentActivity>()
                    .Where(x => x.Topics.Contains(topic))
                    .RowCount();

            if (topicUsage == 0)
            {
                this.Session.Delete(topic);
            }
        }

        /// <summary>
        /// The update topic.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void UpdateTopic(UpdateTopicCommand cmd)
        {
            if (cmd.Dto != null)
            {
                var topic = this.Session.Get<Topic>(cmd.Dto.ID);
                if (topic != null)
                {
                    topic.Title = cmd.Dto.Title;
                    this.Session.Update(topic);
                }
            }
        }

        /// <summary>
        /// The sort.
        /// </summary>
        /// <param name="list">
        ///     The list.
        /// </param>
        /// <returns>
        /// The ordered list of topics.
        /// </returns>
        private IEnumerable<Topic> Sort(IEnumerable<Topic> list)
        {
            return list.OrderBy(x => x.Title);
        }

        #endregion
    }
}